package com.boot.down.util;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Json<T> {

    private static final Logger LOGGER = LogManager.getLogger(Json.class);

    /**
     * 结果编码，详见{@link Response}
     */

    private final int code;

    /**
     * 显示的消息
     */
    private final String msg;

    /**
     * 传输的具体数据
     */
    private final T data;

    /**
     * 操作是否成功
     *
     * @return true表示操作成功
     */
    public boolean success() {
        return code == Response.OK.getCode();
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public T getData() {
        return data;
    }

    private Json(JsonBuilder<T> builder) {
        this.code = builder.code;
        this.msg = builder.msg;
        this.data = builder.data;
    }

    public static <T> Json.JsonBuilder<T> build() {
        return new JsonBuilder<>();
    }

    public static <T> Json.JsonBuilder<T> build(Response response, String msg) {
        return new JsonBuilder<>(response, msg);
    }

    public static <T> Json.JsonBuilder<T> build(T data) {
        return new JsonBuilder<>(data);
    }

    public static <String> Json.JsonBuilder<String> build(Message message) {
        return new JsonBuilder<String>(message);
    }

    public static <T> Json.JsonBuilder<T> build(Message message, T data) {
        return new JsonBuilder<>(message, data);
    }

    public static final class JsonBuilder<T> {
        private int code = Response.OK.getCode();

        private String msg;

        private T data;

        private JsonBuilder() {
        }

        /**
         * 构建返回的JSON
         *
         * @param response 返回状态
         * @param msg      返回消息内容
         */
        private JsonBuilder(Response response, String msg) {
            code(response);
            msg(msg);
        }

        /**
         * 构建返回的JSON，默认返回成功，消息为空
         *
         * @param data 返回的数据
         */
        private JsonBuilder(T data) {
            data(data);
        }

        /**
         * 通过方法调用消息对象构建Json,Messaage.success为true返回200，为false返回500
         * msg等于Message.lastMessage
         *
         * @param message 方法调用消息对象
         */
        public JsonBuilder(Message message) {
            setMessage(message);
        }

        /**
         * 通过方法调用消息对象构建Json,Messaage.success为true返回200，为false返回500
         * msg等于Message.lastMessage
         *
         * @param message 方法调用消息对象
         * @param data    返回的数据
         */
        public JsonBuilder(Message message, T data) {
            setMessage(message);
            this.data = data;
        }

        private void setMessage(Message message) {
            this.msg = message.getLashMessaage();
            if (!message.isSuccess()) {
                this.code = Response.INVALID.getCode();
            }
        }

        /**
         * 设置Json返回的编码
         *
         * @param response 取值见{@link Response}
         * @return JsonBuilder
         */
        public JsonBuilder<T> code(Response response) {
            if (null != response) {
                this.code = response.getCode();
            }
            return this;
        }

        /**
         * 操作成功的Json信息
         *
         * @param msg 反馈给前端的显示消息
         * @return JsonBuilder
         */
        public JsonBuilder<T> successMsg(String msg) {
            this.code = Response.OK.getCode();
            msg(msg);
            return this;
        }

        /**
         * 操作失败的Json信息
         *
         * @param msg 反馈给前端的显示消息
         * @return JsonBuilder
         */
        public JsonBuilder<T> errorMsg(String msg) {
            this.code = Response.ERROR.getCode();
            msg(msg);
            return this;
        }

        /**
         * 设置反馈给前端的消息
         *
         * @param msg 显示的消息
         * @return JsonBuilder
         */
        public JsonBuilder<T> msg(String msg) {
            this.msg = msg;
            return this;
        }

        /**
         * 设置Json中传输的数据
         *
         * @param data 传输数据
         * @return JsonBuilder
         */
        public JsonBuilder<T> data(T data) {
            this.data = data;
            return this;
        }

        /**
         * 设置响应状态
         *
         * @param status 状态值
         * @return JsonBuilder
         */
        public JsonBuilder<T> status(boolean status) {
            if (status) {
                code(Response.OK);
            } else {
                code(Response.ERROR);
            }
            return this;
        }

        /**
         * 输出Json对象
         *
         * @return json信息
         */
        public Json<T> output() {
            if (LOGGER.isDebugEnabled() && Response.OK.getCode() != code && msg == null) {
                LOGGER.debug("当前请求状态为：" + code + ",但未设置对应的msg，请检查");
            }
            return new Json<>(this);
        }
    }

    @Override
    public String toString() {
        return String.format("Json{code=%s,msg=%s,data=%s}", code, msg, data);
    }
}
